// ======================= 工具方法 开始 ======================= //
  function aesDecryptAccountList(GMkey) {
    var encryptStr = GM_getValue(GMkey, "");
    if (encryptStr === "") return [];
    var res = JSON.parse(aesDecrypt(encryptStr, GMkey));
    if (typeof res === "string") {
      res = JSON.parse(res);
    }
    return res;
  }
  function aesEncrypt(text, key) {
    if (typeof key === "undefined" || key === null) {
      throw new Error("加密密钥不能为空");
    }
    if (typeof text === "undefined" || text === null) {
      throw new Error("加密文本不能为空");
    }
    const fixedKey = CryptoJS.enc.Utf8.parse(
      key.toString().padEnd(32, "0").slice(0, 32)
    );
    const encrypted = CryptoJS.AES.encrypt(
      CryptoJS.enc.Utf8.parse(text),
      fixedKey,
      { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }
    );
    return encrypted.toString();
  }
  function aesDecrypt(cipherText, key) {
    if (typeof key === "undefined" || key === null) {
      throw new Error("解密密钥不能为空");
    }
    if (typeof cipherText === "undefined" || cipherText === null) {
      throw new Error("解密文本不能为空");
    }
    const fixedKey = CryptoJS.enc.Utf8.parse(
      key.toString().padEnd(32, "0").slice(0, 32)
    );
    const decrypted = CryptoJS.AES.decrypt(cipherText, fixedKey, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    });
    return decrypted.toString(CryptoJS.enc.Utf8);
  }
  function base64Encode(text) {
    return btoa(unescape(encodeURIComponent(text)));
  }
  function accountEncrypt(account, password, name) {
    JSON.stringify({ account: account, password: password });
    return aesEncrypt(
      JSON.stringify({ account: account, password: password }),
      base64Encode(name)
    );
  }
  // 增强版模拟输入 - 更贴近原生行为
  function simulateNativeInput($input, text, delay = 150) {
    // 确保输入框获得焦点
    const inputElement = $input[0];
    inputElement.focus();

    // 清空输入框（模拟手动删除）
    inputElement.value = "";
    triggerInputEvent(inputElement, "input");

    // 逐个字符输入
    text.split("").forEach((char, index) => {
      setTimeout(() => {
        // 1. 保存当前光标位置
        const selectionStart = inputElement.selectionStart;
        const selectionEnd = inputElement.selectionEnd;

        // 2. 触发keydown事件（包含更多细节）
        const keyDownEvent = new KeyboardEvent("keydown", {
          key: char,
          code: `Key${char.toUpperCase()}`,
          keyCode: char.charCodeAt(0),
          which: char.charCodeAt(0),
          bubbles: true,
          cancelable: true,
          composed: true,
          // 移除或替换view属性
          view: document.defaultView, // 使用document.defaultView替代window
        });
        inputElement.dispatchEvent(keyDownEvent);

        // 3. 触发keypress事件
        const keyPressEvent = new KeyboardEvent("keypress", {
          key: char,
          code: `Key${char.toUpperCase()}`,
          keyCode: char.charCodeAt(0),
          which: char.charCodeAt(0),
          bubbles: true,
          cancelable: true,
          composed: true,
          view: document.defaultView, // 使用document.defaultView替代window
        });
        inputElement.dispatchEvent(keyPressEvent);

        // 4. 手动更新值（模拟输入）
        const currentValue = inputElement.value;
        const newValue =
          currentValue.substring(0, selectionStart) +
          char +
          currentValue.substring(selectionEnd);
        inputElement.value = newValue;

        // 5. 触发input事件（框架主要监听这个）
        triggerInputEvent(inputElement, "input");

        // 6. 触发textInput事件（部分框架依赖）
        const textInputEvent = new InputEvent("textInput", {
          data: char,
          inputType: "insertText",
          bubbles: true,
          cancelable: true,
          composed: true,
          view: document.defaultView, // 使用document.defaultView替代window
        });
        inputElement.dispatchEvent(textInputEvent);

        // 7. 更新光标位置
        inputElement.selectionStart = inputElement.selectionEnd =
          selectionStart + 1;

        // 8. 触发keyup事件
        const keyUpEvent = new KeyboardEvent("keyup", {
          key: char,
          code: `Key${char.toUpperCase()}`,
          keyCode: char.charCodeAt(0),
          which: char.charCodeAt(0),
          bubbles: true,
          cancelable: true,
          composed: true,
          view: document.defaultView, // 使用document.defaultView替代window
        });
        inputElement.dispatchEvent(keyUpEvent);

        // 9. 最后一个字符输入完成后触发change事件
        if (index === text.length - 1) {
          triggerInputEvent(inputElement, "change");
          // 失去焦点（模拟用户输入完成后移开）
          inputElement.blur();
        }
      }, index * delay);
    });
  }
  // 触发输入事件的辅助函数（处理不同框架的兼容性）
  function triggerInputEvent(element, type) {
    // 创建基础事件
    const event = new Event(type, {
      bubbles: true,
      cancelable: true,
      composed: true,
    });

    // 对于React框架，添加特殊属性
    if (type === "input") {
      Object.defineProperty(event, "target", {
        value: element,
        writable: false,
      });
    }

    element.dispatchEvent(event);
  }
  /**
   * 创建透明点击区域的通用方法
   * @param {Object} options - 配置选项
   * @param {string} options.position - 位置，可选值:
   *   四角: 'top-left', 'top-right', 'bottom-left', 'bottom-right'
   *   四边中间: 'top-center', 'right-center', 'bottom-center', 'left-center'
   * @param {number} [options.width=72] - 宽度，默认72px
   * @param {number} [options.height=72] - 高度，默认72px
   * @param {number} [options.zIndex=999999] - z-index值，默认999999
   * @param {Function} options.onClick - 点击事件处理函数
   * @param {string} [options.id] - 元素ID，不提供则自动生成
   * @param {string} [options.hoverColor='rgba(0, 123, 255, 0.1)'] - hover时的背景色
   * @returns {jQuery} 创建的元素
   */
  function createTransparentClickBox(options) {
    // 默认配置
    const defaults = {
      width: 72,
      height: 72,
      zIndex: 999999,
      hoverColor: "rgba(0, 123, 255, 0.1)",
      position: "bottom-right",
    };

    // 合并配置
    const settings = { ...defaults, ...options };

    // 验证必要参数
    if (typeof settings.onClick !== "function") {
      console.error("必须提供onClick回调函数");
      return null;
    }

    // 位置配置映射表
    const positionStyles = {
      "top-left": {
        top: `-${settings.height / 2}px`,
        left: `-${settings.width / 2}px`,
      },
      "top-right": {
        top: `-${settings.height / 2}px`,
        right: `-${settings.width / 2}px`,
      },
      "bottom-left": {
        bottom: `-${settings.height / 2}px`,
        left: `-${settings.width / 2}px`,
      },
      "bottom-right": {
        bottom: `-${settings.height / 2}px`,
        right: `-${settings.width / 2}px`,
      },
      "top-center": {
        top: `-${settings.height / 2}px`,
        left: "50%",
        transform: "translateX(-50%)",
      },
      "right-center": {
        right: `-${settings.width / 2}px`,
        top: "50%",
        transform: "translateY(-50%)",
      },
      "bottom-center": {
        bottom: `-${settings.height / 2}px`,
        left: "50%",
        transform: "translateX(-50%)",
      },
      "left-center": {
        left: `-${settings.width / 2}px`,
        top: "50%",
        transform: "translateY(-50%)",
      },
    };

    // 检查位置是否有效
    if (!positionStyles[settings.position]) {
      console.error("无效的位置参数，请检查position值");
      return null;
    }

    // 创建元素
    const $clickBox = $("<div>", {
      id: settings.id || `transparent-click-box-${Date.now()}`,
      css: {
        width: `${settings.width}px`,
        height: `${settings.height}px`,
        position: "fixed",
        zIndex: settings.zIndex,
        backgroundColor: "transparent",
        cursor: "pointer",
        ...positionStyles[settings.position],
      },
    });

    // 添加到页面
    $("body").append($clickBox);

    // 绑定点击事件
    $clickBox.on("click", function (e) {
      e.stopPropagation();
      settings.onClick(e, $clickBox); // 传递事件和元素本身
    });

    // 绑定hover事件
    $clickBox.hover(
      function () {
        $(this).css("backgroundColor", settings.hoverColor);
      },
      function () {
        $(this).css("backgroundColor", "transparent");
      }
    );

    return $clickBox;
  }
  /**
   * 等待元素出现的通用方法
   * @param {*} selector 查找元素 JQuery选择器
   * @param {*} options 配置选项
   *   - interval: 检查间隔时间(毫秒)，默认500ms
   *   - maxAttempts: 最大尝试次数，默认100次
   * @returns
   */
  function waitForElement(selector, options = {}) {
    var $deferred = window.jQuery.Deferred();
    // 默认配置
    const defaults = {
      interval: 500,
      maxAttempts: 20,
    };

    // 合并配置
    const config = { ...defaults, ...options };
    let attempts = 0;

    // 检查元素是否存在的函数
    function checkElement() {
      attempts++;
      // 检查元素是否存在
      if (window.jQuery(selector).length > 0) {
        $deferred.resolve(window.jQuery(selector), config);
        return;
      }
      // 达到最大尝试次数，执行超时回调
      if (attempts >= config.maxAttempts) {
        $deferred.reject("timeout", config);
        return;
      }
      // 继续检查
      setTimeout(checkElement, config.interval);
    }
    checkElement();
    return $deferred.promise();
  }
  // 使用示例
  // 1. 基础用法 - 复制ID为"content"的元素内容
  // copyElementContent('#content');
  /**
   * 复制指定元素内容的通用方法
   * @param {string|HTMLElement} target - 目标元素的选择器或DOM元素
   * @param {Object} options - 配置选项
   * @param {Function} [options.onSuccess] - 复制成功回调
   * @param {Function} [options.onError] - 复制失败回调
   * @param {string} [options.successMessage='复制成功'] - 默认成功提示文本
   * @param {string} [options.errorMessage='复制失败，请手动复制'] - 默认失败提示文本
   * @returns {void}
   */
  function copyElementContent(target, options = {}) {
    // 处理默认配置
    const defaults = {
      onSuccess: null,
      onError: null,
      successMessage: "复制成功",
      errorMessage: "复制失败，请手动复制",
    };

    const config = { ...defaults, ...options };
    let targetElement;

    // 获取目标元素
    if (typeof target === "string") {
      targetElement = document.querySelector(target);
    } else if (target instanceof HTMLElement) {
      targetElement = target;
    }

    // 验证目标元素是否存在
    if (!targetElement) {
      console.error("复制失败：目标元素不存在");
      if (typeof config.onError === "function") {
        config.onError(new Error("目标元素不存在"), config.errorMessage);
      }
      return;
    }

    // 创建临时复制按钮
    const tempButton = document.createElement("button");
    tempButton.style.position = "absolute";
    tempButton.style.left = "-9999px";
    tempButton.setAttribute(
      "data-clipboard-target",
      `#${targetElement.id || `temp-${Date.now()}`}`
    );

    // 如果目标元素没有ID，临时添加一个
    if (!targetElement.id) {
      targetElement.id = tempButton
        .getAttribute("data-clipboard-target")
        .slice(1);
    }

    // 添加到文档
    document.body.appendChild(tempButton);

    // 初始化Clipboard
    const clipboard = new ClipboardJS(tempButton);

    // 复制成功处理
    clipboard.on("success", (e) => {
      e.clearSelection();

      // 执行回调
      if (typeof config.onSuccess === "function") {
        config.onSuccess(e.text, config.successMessage);
      } else {
        // 默认提示
        layer.msg(config.successMessage);
      }

      // 清理
      cleanup();
    });

    // 复制失败处理
    clipboard.on("error", (e) => {
      if (typeof config.onError === "function") {
        config.onError(e, config.errorMessage);
      } else {
        // 默认提示
        layer.msg(config.errorMessage);
      }

      // 清理
      cleanup();
    });

    // 清理函数
    function cleanup() {
      clipboard.destroy();
      document.body.removeChild(tempButton);
      // 移除临时ID
      if (targetElement.id.startsWith("temp-")) {
        targetElement.removeAttribute("id");
      }
    }

    // 触发复制
    tempButton.click();
  }
  // ======================= 工具方法 结束 ======================= //